﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TumbaloSoft.Models;
using System.Collections;
using TumbaloSoft.Helpers;
using TumbaloSoft.Helpers.QueryObjects;

namespace TumbaloSoft.Controllers
{
    public class PropietarioController : TumbaloController
    {
        private static Object lockObject = new Object();
        private static Object lockAsignar = new Object(); 
        
        public ActionResult Index(BusquedaPropietario propietarioBuscar)
        {
            if (defaultAction != null) return defaultAction;

            int numActivos = 0;
            try
            {
                ViewBag.lista = HelperInmueble.selectAll();
                numActivos = HelperPropietario.selectCountActivos();
                ViewBag.ListaPropietarios = HelperPropietario.buscar(propietarioBuscar);
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar la lista de propietarios", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            ViewBag.prevPage = propietarioBuscar.prPage - 1;
            ViewBag.nextPage = propietarioBuscar.prPage + 1;
            ViewBag.numPages = numActivos / propietarioBuscar.prPageSize;
            if ((numActivos % propietarioBuscar.prPageSize) > 0) ViewBag.numPages++;

            return View(propietarioBuscar);
        }

        public ActionResult Asignar(int? idPropietario, BusquedaInmueble inmuebleBuscar, bool? error)
        {
            if (defaultAction != null) return defaultAction;

            inmuebleBuscar.prPageSize = Int32.MaxValue;
            if (!idPropietario.HasValue) return HttpNotFound();
            IList listaDistritos = null;
            try
            {
                ViewBag.listaTipoInmueble = HelperTipoInmueble.selectAll();
                listaDistritos = HelperDistrito.selectAll();
                inmuebleBuscar.prTipoInmueble = new TipoInmueble();
                ViewBag.ListaInmueble = HelperInmueble.buscar(inmuebleBuscar);
                ViewBag.ListaTitulos = HelperTituloDePropiedad.selectActivosByIdPropietario(idPropietario.Value);
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar la lista de titulos de propiedad", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            List<int> lista = new List<int>();
            foreach (TituloDePropiedad t in ViewBag.ListaTitulos)
            {
                lista.Add(t.prInmueble.prIdInmueble);
            }
            ViewBag.lista = lista;
            ViewBag.listaDistritos = listaDistritos;
            ViewBag.idPropietario = idPropietario.Value;
            if (error.HasValue && error.Value) ViewBag.MensajeError = "Los valores deben ser menores que 100 y mayores que 0";
            return View(inmuebleBuscar);
        }

        [HttpPost]
        public ActionResult Asignar(int idPropietario, List<int> listaPresentes, List<int> listaInmuebles,List<int> listaPorcentajes)
        {
            if (defaultAction != null) return defaultAction;

            bool error = false; 
            foreach (int porc in listaPorcentajes)
            {
                if (porc > 100 || porc < 0) error = true;
            }
            if (error)
            {
                return Asignar(idPropietario,new BusquedaInmueble(),true);
            }
            lock (lockAsignar)
            {
                for (int i = 0; i < listaPresentes.Count; i++)
                {
                    TituloDePropiedad titulo = new TituloDePropiedad();
                    titulo.prInmueble = new Inmueble();
                    titulo.prInmueble.prIdInmueble = listaPresentes[i];
                    titulo.prPropietario = new Propietario();
                    titulo.prPropietario.prIdPropietario = idPropietario;
                    TituloDePropiedad tituloExistente;
                    try
                    {
                        tituloExistente = HelperTituloDePropiedad.siExiste(titulo);
                    }
                    catch(Exception ex)
                    {
                        Logger.Current.Error("Ocurrio un error al verificar existencia de titulo de propiedad", ex);
                        return View("~/Views/Shared/Error.cshtml");
                    }
                    if (tituloExistente == null && listaInmuebles != null && listaInmuebles.Contains(listaPresentes[i]))
                    {
                        tituloExistente = new TituloDePropiedad();
                        tituloExistente.prInmueble = new Inmueble();
                        tituloExistente.prInmueble.prIdInmueble = listaPresentes[i];
                        tituloExistente.prPropietario = new Propietario();
                        tituloExistente.prPropietario.prIdPropietario = idPropietario;
                        tituloExistente.prPorcentajePropiedad = listaPorcentajes[i];
                        try
                        {
                            HelperTituloDePropiedad.insert(tituloExistente);
                        }
                        catch(Exception ex)
                        {
                            Logger.Current.Error("Ocurrio un error al insertar titulo de propiedad", ex);
                            return View("~/Views/Shared/Error.cshtml");
                        }
                    }
                    else
                    {
                        if (tituloExistente != null && (listaInmuebles == null || !listaInmuebles.Contains(listaPresentes[i])))
                        {
                            if (tituloExistente.prEstado != "ELIMINADO")
                                try
                                {
                                    HelperTituloDePropiedad.delete(tituloExistente);
                                }
                                catch(Exception ex)
                                {
                                    Logger.Current.Error("Ocurrio un error al eliminar un titulo de propiedad", ex);
                                    return View("~/Views/Shared/Error.cshtml");
                                }
                        }
                        if (tituloExistente != null && listaInmuebles != null && listaInmuebles.Contains(listaPresentes[i]))
                        {
                            tituloExistente.prPorcentajePropiedad = listaPorcentajes[i];
                            tituloExistente.prEstado = "ACTIVO";
                            try
                            {
                                HelperTituloDePropiedad.update(tituloExistente);
                            }
                            catch(Exception ex)
                            {
                                Logger.Current.Error("Ocurrio un error al actualizar un titulo de propiedad", ex);
                                return View("~/Views/Shared/Error.cshtml");
                            }
                        }

                    }
                }
            }
            ViewBag.mensaje="Se asignaron los inmuebles con exito";
            ViewBag.returnURL="/propietario/modificar?id="+ idPropietario;
            return View("~/Views/Shared/Exito.cshtml");
        }

        public ActionResult Nuevo()
        {
            if (defaultAction != null) return defaultAction;

            try
            {
                ViewBag.listaTipos = HelperTipoDocumento.selectAll();
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar los tipos de documento", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            return View();
        }

        [HttpPost]
        public ActionResult Nuevo(Propietario prop)
        {
            if (defaultAction != null) return defaultAction;

            int id;
            try
            {
                ViewBag.listaTipos = HelperTipoDocumento.selectAll();  
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar los tipos de documento", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            
            //al no recibir el codigo en el post hay que eliminar el error ya que se calcula automaticamente
            ModelState.Remove("prIdPropietario");
            ModelState.Remove("prDireccion");//no hay direccion en el propietario?
            if (ModelState.IsValid)
            {
                try
                {
                    lock (lockObject)
                    {
                        id = HelperPropietario.selectMaxCodigo() + 1;
                        prop.prIdPropietario = id;
                        prop.prIdPersona = id;
                        HelperPropietario.insert(prop);
                    }
                }
                catch(Exception ex)
                {
                    Logger.Current.Error("Ocurrio un error al insertar un propietario", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
                AccountController.crearCuenta(prop, 1);
                ViewBag.mensaje = "Se registro correctamente el propietario con ID= " + prop.prIdPropietario;
                ViewBag.returnURL = "/propietario/modificar?id="+prop.prIdPropietario;
                return View("~/Views/Shared/Exito.cshtml");
            }
            else return View(prop);
        }

        public ActionResult Modificar(int? id)
        {
            if (defaultAction != null) return defaultAction;

            if (!id.HasValue) return HttpNotFound("Esta página no existe");//se llamo sin parametro deberia devolver error
            Propietario propietario;
            try
            {
                ViewBag.listaTipos = HelperTipoDocumento.selectAll();
                propietario = HelperPropietario.selectById(id.Value);
                if (propietario == null) return HttpNotFound("No existe el propietario con el código " + id.Value);//si el propietario no se encontró
                List<TituloDePropiedad> titulos =HelperTituloDePropiedad.selectActivosByIdPropietario(id.Value) ;
                List<Inmueble> inmuebles = new List<Inmueble>();
                foreach (TituloDePropiedad t in titulos)
                {

                    inmuebles.Add(HelperInmueble.selectById(t.prInmueble.prIdInmueble));
                }
                ViewBag.inmuebles = inmuebles;
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar un propietario y sus propiedades", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            return View(propietario);

        }

        [HttpPost]
        public ActionResult Modificar(Propietario prop )
        {
            if (defaultAction != null) return defaultAction;

            ModelState.Remove("prDireccion");
            if (ModelState.IsValid)
            {
                try
                {
                    ViewBag.listaTipos = HelperTipoDocumento.selectAll();
                    HelperPropietario.update(prop);
                }
                catch(Exception ex)
                {
                    Logger.Current.Error("Ocurrio un error al modificar un propietario", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
                ViewBag.mensaje = "Se modificó correctamente el propietario con ID= " + prop.prIdPropietario;
                ViewBag.returnURL = "/propietario/modificar?id=" + prop.prIdPropietario;
                return View("~/Views/Shared/Exito.cshtml");
            }
            try
            {
                ViewBag.listaTipos = HelperTipoDocumento.selectAll();
                List<TituloDePropiedad> titulos = HelperTituloDePropiedad.selectActivosByIdPropietario(prop.prIdPropietario);
                List<Inmueble> inmuebles = new List<Inmueble>();
                foreach (TituloDePropiedad t in titulos)
                {

                    inmuebles.Add(HelperInmueble.selectById(t.prInmueble.prIdInmueble));
                }
                ViewBag.inmuebles = inmuebles;
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar un propietario y sus propiedades", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            return View(prop);
        }

        public ActionResult Eliminar(int? id)
        {
            if (defaultAction != null) return defaultAction;

            if (!id.HasValue) return HttpNotFound("Esta página no existe");//se llamo sin parametro deberia devolver error
            Propietario propietario;
            try
            {
                ViewBag.listaTipos = HelperTipoDocumento.selectAll();
                propietario = HelperPropietario.selectById(id.Value);
            }
            catch(Exception ex)
            {
                Logger.Current.Error("Ocurrio un error al cargar un propietario y su lista de propiedades", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            if (propietario == null) return HttpNotFound("No existe el propietario con el código " + id.Value);//si el propietario no se encontró
            return View(propietario);
        }
        [HttpPost]
        public ActionResult Eliminar(Propietario prop)
        {
            if (defaultAction != null) return defaultAction;

            ModelState.Remove("prDireccion");
            if (ModelState.IsValid)
            {
                try
                {
                    ViewBag.listaTipos = HelperTipoDocumento.selectAll();
                    HelperPropietario.delete(prop);
                }
                catch(Exception ex)
                {
                    Logger.Current.Error("Ocurrio un error al eliminar un propietario", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
            }
            ViewBag.mensaje = "Se eliminó correctamente el propietario con ID= " + prop.prIdPropietario;
            ViewBag.returnURL = "/propietario";
            return View("~/Views/Shared/Exito.cshtml");
        }

    }
}

